import os
import time
import shutil
import errno
import bisect
from enum import Enum
from typing import Optional, List, Dict, Any, Tuple, BinaryIO
from dataclasses import dataclass, field
from pathlib import Path
import struct

# 常量定义
MAX_FILENAME_LEN = 256
MAX_PATH_LEN = 1024
MAX_CONTENT_LEN = 8192
DISK_ID_LEN = 32
ALGORITHM_PATH_LEN = 256
FILE_PREFIX_LEN = 20
MAX_LINK_DEPTH = 10
MAX_FILES_PER_BLOCK = 30
MAX_BLOCK_SIZE = 1024 * 1024 * 1024
LOCAL_ID_LENGTH = 8

# 错误代码
class TDOSError(Enum):
    SUCCESS = 0
    FILE_NOT_FOUND = -1
    INVALID_PATH = -2
    ALREADY_EXISTS = -3
    DISK_CORRUPTED = -4
    IO_ERROR = -5
    INVALID_MODE = -6
    NOT_A_DIRECTORY = -7
    NOT_A_FILE = -8
    LINK_LOOP = -9
    INVALID_LINK = -10
    MEMORY_ERROR = -11
    DISK_FULL = -12
    ID_ALLOCATION_ERROR = -13
    BLOCK_FULL = -14

# 错误消息映射
ERROR_MESSAGES = {
    TDOSError.SUCCESS: "Success",
    TDOSError.FILE_NOT_FOUND: "File not found",
    TDOSError.INVALID_PATH: "Invalid path",
    TDOSError.ALREADY_EXISTS: "Already exists",
    TDOSError.DISK_CORRUPTED: "Disk corrupted",
    TDOSError.IO_ERROR: "I/O error",
    TDOSError.INVALID_MODE: "Invalid mode",
    TDOSError.NOT_A_DIRECTORY: "Not a directory",
    TDOSError.NOT_A_FILE: "Not a file",
    TDOSError.LINK_LOOP: "Link loop detected",
    TDOSError.INVALID_LINK: "Invalid link",
    TDOSError.MEMORY_ERROR: "Memory allocation error",
    TDOSError.DISK_FULL: "Disk full",
    TDOSError.ID_ALLOCATION_ERROR: "ID allocation error",
    TDOSError.BLOCK_FULL: "Storage block full"
}

def tdos_strerror(error_code: TDOSError) -> str:
    """获取错误消息"""
    return ERROR_MESSAGES.get(error_code, "Unknown error")

# 文件类型
class FileType(Enum):
    REGULAR_FILE = 0
    DIRECTORY = 1
    LINK_FILE = 2

@dataclass
class FileNode:
    """文件系统节点"""
    name: str
    type: FileType
    parent_path: str = ""
    content_ref: str = ""
    link_target: str = ""
    create_time: float = 0.0
    modify_time: float = 0.0
    local_id: str = "00000000"
    first_child: Optional['FileNode'] = None
    next_sibling: Optional['FileNode'] = None
    children_by_id: Dict[str, 'FileNode'] = field(default_factory=dict)
    sorted_child_ids: List[str] = field(default_factory=list)

@dataclass
class StorageBlock:
    """存储块信息"""
    block_id: str
    file_count: int = 0
    total_size: int = 0
    file_entries: Dict[str, Tuple[int, int]] = field(default_factory=dict)

@dataclass
class BIOSData:
    """磁盘信息"""
    disk_id: str = ""
    algorithm_path: str = ""
    root_path: str = ""
    disk_name: str = ""
    next_block_id: int = 0
    next_local_id: int = 2

class TDOSHandle:
    """文件系统操作句柄"""
    def __init__(self):
        self.root_node: Optional[FileNode] = None
        self.bios_data = BIOSData()
        self.current_path: str = "/"
        self.disk_root_dir: str = ""
        self.disk_modified: bool = False
        self.storage_blocks: Dict[str, StorageBlock] = {}

class TDOS:
    """文本磁盘操作系统"""
    
    def __init__(self):
        self.handle: Optional[TDOSHandle] = None
    
    def mkdir_p(self, path: str) -> TDOSError:
        """创建目录（包括父目录）"""
        try:
            Path(path).mkdir(parents=True, exist_ok=True)
            return TDOSError.SUCCESS
        except OSError as e:
            print(f"Error creating directory '{path}': {e}")
            return TDOSError.IO_ERROR
    
    def _file_exists(self, path: str) -> bool:
        """检查文件是否存在"""
        return Path(path).exists()
    
    def _read_file(self, path: str) -> Tuple[TDOSError, str]:
        """读取文件内容"""
        try:
            with open(path, 'r', encoding='utf-8') as f:
                content = f.read(MAX_CONTENT_LEN)
                return TDOSError.SUCCESS, content
        except IOError as e:
            print(f"Error reading file '{path}': {e}")
            return TDOSError.IO_ERROR, ""
    
    def _write_file(self, path: str, content: str) -> TDOSError:
        """写入文件内容"""
        try:
            with open(path, 'w', encoding='utf-8') as f:
                f.write(content)
            return TDOSError.SUCCESS
        except IOError as e:
            print(f"Error writing file '{path}': {e}")
            return TDOSError.IO_ERROR
    
    def _remove_file(self, path: str) -> TDOSError:
        """删除文件"""
        try:
            Path(path).unlink()
            return TDOSError.SUCCESS
        except IOError as e:
            print(f"Error removing file '{path}': {e}")
            return TDOSError.IO_ERROR
    
    def _parse_bios(self, content: str) -> TDOSError:
        """解析BIOS内容"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        for line in content.split('\n'):
            if line.startswith('disk_id:'):
                self.handle.bios_data.disk_id = line[8:].strip()
            elif line.startswith('algorithm_path:'):
                self.handle.bios_data.algorithm_path = line[15:].strip()
            elif line.startswith('root_path:'):
                self.handle.bios_data.root_path = line[10:].strip()
            elif line.startswith('disk_name:'):
                self.handle.bios_data.disk_name = line[10:].strip()
            elif line.startswith('next_block_id:'):
                try:
                    self.handle.bios_data.next_block_id = int(line[14:].strip())
                except ValueError:
                    self.handle.bios_data.next_block_id = 0
            elif line.startswith('next_local_id:'):
                try:
                    self.handle.bios_data.next_local_id = int(line[14:].strip())
                except ValueError:
                    self.handle.bios_data.next_local_id = 2
        
        return TDOSError.SUCCESS
    
    def _generate_bios(self) -> Tuple[TDOSError, str]:
        """生成BIOS内容"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        content = f"disk_id:{self.handle.bios_data.disk_id}\n"
        content += f"algorithm_path:{self.handle.bios_data.algorithm_path}\n"
        content += f"root_path:{self.handle.bios_data.root_path}\n"
        content += f"disk_name:{self.handle.bios_data.disk_name}\n"
        content += f"next_block_id:{self.handle.bios_data.next_block_id}\n"
        content += f"next_local_id:{self.handle.bios_data.next_local_id}\n"
        
        return TDOSError.SUCCESS, content
    
    def _parse_filetree(self, content: str) -> TDOSError:
        """解析文件树内容"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        # 首先创建根节点
        self.handle.root_node = FileNode(
            name="/",
            type=FileType.DIRECTORY,
            parent_path="",
            create_time=time.time(),
            modify_time=time.time(),
            local_id="00000000"
        )
        
        # 为根节点添加特殊目录项
        self._add_special_directories(self.handle.root_node)
        
        # 读取并解析文件树结构
        for line in content.split('\n'):
            if not line or line.startswith('#') or line.startswith('\n'):
                continue  # 跳过注释和空行
            
            parts = line.split(':')
            if len(parts) < 8:
                continue  # 跳过格式错误的行
            
            path = parts[0]
            type_str = parts[1]
            parent_path = parts[2]
            content_ref = parts[3] if len(parts) > 3 else ""
            link_target = parts[4] if len(parts) > 4 else ""
            local_id = parts[5] if len(parts) > 5 else "00000000"
            
            try:
                create_time = float(parts[6]) if len(parts) > 6 else time.time()
                modify_time = float(parts[7]) if len(parts) > 7 else time.time()
            except ValueError:
                create_time = time.time()
                modify_time = time.time()
            
            # 确定文件类型
            if type_str == "DIR":
                file_type = FileType.DIRECTORY
            elif type_str == "LINK":
                file_type = FileType.LINK_FILE
            else:
                file_type = FileType.REGULAR_FILE
            
            # 创建节点
            new_node = FileNode(
                name=Path(path).name,
                type=file_type,
                parent_path=parent_path,
                content_ref=content_ref,
                link_target=link_target,
                create_time=create_time,
                modify_time=modify_time,
                local_id=local_id
            )
            
            # 找到父节点并添加
            parent_node = self._find_node(parent_path)
            if parent_node and parent_node.type == FileType.DIRECTORY:
                # 添加到父节点的子节点链表
                new_node.next_sibling = parent_node.first_child
                parent_node.first_child = new_node
                
                # 添加到父节点的快速查找结构
                parent_node.children_by_id[local_id] = new_node
                bisect.insort(parent_node.sorted_child_ids, local_id)
                
                parent_node.modify_time = time.time()
                
                # 如果是目录，添加特殊目录项
                if new_node.type == FileType.DIRECTORY:
                    self._add_special_directories(new_node)
        
        return TDOSError.SUCCESS
    
    def _add_special_directories(self, dir_node: FileNode):
        """为目录节点添加特殊目录项（. 和 ..）"""
        if dir_node.type != FileType.DIRECTORY:
            return
        
        # 当前目录项
        dot_node = FileNode(
            name=".",
            type=FileType.LINK_FILE,
            parent_path=dir_node.parent_path,
            link_target=dir_node.parent_path + "/" + dir_node.name if dir_node.parent_path != "/" else "/" + dir_node.name,
            create_time=dir_node.create_time,
            modify_time=dir_node.modify_time,
            local_id="00000000"
        )
        
        # 父目录项
        dot_dot_node = FileNode(
            name="..",
            type=FileType.LINK_FILE,
            parent_path=dir_node.parent_path,
            link_target=dir_node.parent_path,
            create_time=dir_node.create_time,
            modify_time=dir_node.modify_time,
            local_id="00000001"
        )
        
        # 添加到子节点链表
        dot_dot_node.next_sibling = dot_node
        dot_node.next_sibling = dir_node.first_child
        dir_node.first_child = dot_dot_node
        
        # 添加到快速查找结构
        dir_node.children_by_id["00000000"] = dot_node
        dir_node.children_by_id["00000001"] = dot_dot_node
        bisect.insort(dir_node.sorted_child_ids, "00000000")
        bisect.insort(dir_node.sorted_child_ids, "00000001")
    
    def _generate_filetree(self, node: Optional[FileNode], parent_path: str = "") -> Tuple[TDOSError, str]:
        """生成文件树内容"""
        if not node:
            return TDOSError.SUCCESS, ""
        
        # 跳过特殊目录项
        if node.name in (".", ".."):
            return TDOSError.SUCCESS, ""
        
        # 确定类型字符串
        if node.type == FileType.DIRECTORY:
            type_str = "DIR"
        elif node.type == FileType.LINK_FILE:
            type_str = "LINK"
        else:
            type_str = "FILE"
        
        # 构建完整路径
        if node.name == "/":
            full_path = "/"
        elif parent_path == "/":
            full_path = f"/{node.name}"
        else:
            full_path = f"{parent_path}/{node.name}"
        
        # 确保字段不为None，否则设置为空字符串
        content_ref = node.content_ref if node.content_ref else ""
        link_target = node.link_target if node.link_target else ""
        local_id = node.local_id if node.local_id else "00000000"
        
        # 添加节点信息到内容
        content = f"{full_path}:{type_str}:{node.parent_path}:{content_ref}:{link_target}:{local_id}:{node.create_time}:{node.modify_time}\n"
        
        # 递归处理子节点
        if node.type == FileType.DIRECTORY:
            child = node.first_child
            while child:
                err, child_content = self._generate_filetree(child, full_path)
                if err != TDOSError.SUCCESS:
                    return err, ""
                content += child_content
                child = child.next_sibling
        
        return TDOSError.SUCCESS, content
    
    def _find_node(self, path: str) -> Optional[FileNode]:
        """查找节点"""
        if not self.handle or not self.handle.root_node:
            return None
        
        # 处理根目录
        if path == "/":
            return self.handle.root_node
        
        # 分割路径成分
        components = [comp for comp in path.split('/') if comp]
        
        # 从根节点开始遍历
        current = self.handle.root_node
        for comp in components:
            if comp == ".":
                continue  # 当前目录
            
            if comp == "..":
                # 父目录
                if current.parent_path:
                    current = self._find_node(current.parent_path)
                continue
            
            # 在子节点中查找
            found = False
            child = current.first_child
            while child:
                if child.name == comp:
                    current = child
                    found = True
                    break
                child = child.next_sibling
            
            if not found:
                return None
        
        return current
    
    def _find_node_by_id(self, parent_node: FileNode, local_id: str) -> Optional[FileNode]:
        """使用二分查找在父节点中根据局部ID查找子节点"""
        if not parent_node or parent_node.type != FileType.DIRECTORY:
            return None
        
        # 使用二分查找在排序的ID列表中查找
        index = bisect.bisect_left(parent_node.sorted_child_ids, local_id)
        if index < len(parent_node.sorted_child_ids) and parent_node.sorted_child_ids[index] == local_id:
            return parent_node.children_by_id[local_id]
        
        return None
    
    def _allocate_local_id(self) -> Tuple[TDOSError, str]:
        """分配一个新的局部ID"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        # 生成新的局部ID
        local_id = f"{self.handle.bios_data.next_local_id:08d}"
        self.handle.bios_data.next_local_id += 1
        
        return TDOSError.SUCCESS, local_id
    
    def _create_node(self, path: str, file_type: FileType, content_ref: str = "", link_target: str = "") -> Tuple[TDOSError, Optional[FileNode]]:
        """创建节点"""
        path_obj = Path(path)
        basename = path_obj.name
        parent_path = str(path_obj.parent)
        
        # 分配局部ID
        err, local_id = self._allocate_local_id()
        if err != TDOSError.SUCCESS:
            return err, None
        
        # 创建新节点
        new_node = FileNode(
            name=basename,
            type=file_type,
            parent_path=parent_path,
            content_ref=content_ref,
            link_target=link_target,
            create_time=time.time(),
            modify_time=time.time(),
            local_id=local_id
        )
        
        return TDOSError.SUCCESS, new_node
    
    def _remove_node(self, node: FileNode) -> TDOSError:
        """移除节点"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        # 递归删除子节点
        if node.type == FileType.DIRECTORY:
            child = node.first_child
            while child:
                next_child = child.next_sibling
                # 跳过特殊目录项
                if child.name not in (".", ".."):
                    self._remove_node(child)
                child = next_child
        elif node.type == FileType.REGULAR_FILE and node.content_ref:
            # 删除内容文件
            if ':' in node.content_ref:  # 新格式：block_id:file_id
                try:
                    block_id, file_id = node.content_ref.split(':')
                    self._remove_file_from_block(block_id, file_id)
                except ValueError:
                    # 如果格式不正确，忽略错误
                    pass
            else:  # 旧格式：直接删除文件
                content_path = os.path.join(self.handle.disk_root_dir, "file", node.content_ref)
                try:
                    Path(content_path).unlink()
                except OSError:
                    pass  # 忽略删除错误
        
        # 从父节点的子节点列表中移除
        parent_node = self._find_node(node.parent_path)
        if parent_node and parent_node.type == FileType.DIRECTORY:
            # 从链表中移除
            prev = None
            curr = parent_node.first_child
            while curr and curr != node:
                prev = curr
                curr = curr.next_sibling
            
            if curr:
                if prev:
                    prev.next_sibling = curr.next_sibling
                else:
                    parent_node.first_child = curr.next_sibling
            
            # 从快速查找结构中移除
            if node.local_id in parent_node.children_by_id:
                del parent_node.children_by_id[node.local_id]
                index = bisect.bisect_left(parent_node.sorted_child_ids, node.local_id)
                if index < len(parent_node.sorted_child_ids) and parent_node.sorted_child_ids[index] == node.local_id:
                    parent_node.sorted_child_ids.pop(index)
        
        return TDOSError.SUCCESS
    
    def _normalize_path(self, path: str) -> Tuple[TDOSError, str]:
        """规范化路径"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        # 处理绝对路径
        if path.startswith('/'):
            return TDOSError.SUCCESS, path
        
        # 处理相对路径
        if self.handle.current_path == '/':
            normalized = f"/{path}"
        else:
            normalized = f"{self.handle.current_path}/{path}"
        
        # 简化路径（处理..和.）
        parts = []
        for part in normalized.split('/'):
            if part == '..':
                if parts:
                    parts.pop()
            elif part and part != '.':
                parts.append(part)
        
        normalized = '/' + '/'.join(parts)
        if normalized == '':  # 处理根目录
            normalized = '/'
        
        return TDOSError.SUCCESS, normalized
    
    def _get_parent_path(self, path: str) -> Tuple[TDOSError, str]:
        """获取父路径"""
        parent = os.path.dirname(path)
        if not parent:
            parent = "/"
        return TDOSError.SUCCESS, parent
    
    def _get_basename(self, path: str) -> Tuple[TDOSError, str]:
        """获取基本名称"""
        return TDOSError.SUCCESS, os.path.basename(path)
    
    def _allocate_block_id(self) -> Tuple[TDOSError, str]:
        """分配一个新的存储块ID"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        block_id = f"s_{self.handle.bios_data.next_block_id:04d}"
        self.handle.bios_data.next_block_id += 1
        
        # 创建新的存储块
        self.handle.storage_blocks[block_id] = StorageBlock(block_id=block_id)
        
        return TDOSError.SUCCESS, block_id
    
    def _find_available_block(self) -> Tuple[TDOSError, str]:
        """查找可用的存储块"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        # 首先尝试查找已有但未满的块
        for block_id, block in self.handle.storage_blocks.items():
            if block.file_count < MAX_FILES_PER_BLOCK and block.total_size < MAX_BLOCK_SIZE:
                return TDOSError.SUCCESS, block_id
        
        # 如果没有可用块，分配新块
        return self._allocate_block_id()
    
    def _write_file_to_block(self, content: str) -> Tuple[TDOSError, str]:
        """将文件内容写入存储块"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        # 查找可用块
        err, block_id = self._find_available_block()
        if err != TDOSError.SUCCESS:
            return err, ""
        
        block = self.handle.storage_blocks[block_id]
        
        # 检查块是否已满
        if block.file_count >= MAX_FILES_PER_BLOCK or block.total_size + len(content) > MAX_BLOCK_SIZE:
            # 尝试分配新块
            err, block_id = self._allocate_block_id()
            if err != TDOSError.SUCCESS:
                return err, ""
            block = self.handle.storage_blocks[block_id]
        
        # 生成文件ID
        file_id = f"{block.file_count:08d}"
        
        # 写入文件内容
        block_path = os.path.join(self.handle.disk_root_dir, "file", f"{block_id}.tdos")
        try:
            # 如果文件不存在，创建它
            if not os.path.exists(block_path):
                with open(block_path, 'wb') as f:
                    pass  # 创建空文件
            
            # 获取文件大小以确定偏移量
            file_size = os.path.getsize(block_path)
            
            # 写入内容
            with open(block_path, 'ab') as f:
                f.write(content.encode('utf-8'))
            
            # 更新块信息
            block.file_entries[file_id] = (file_size, len(content))
            block.file_count += 1
            block.total_size += len(content)
            
            # 返回内容引用
            content_ref = f"{block_id}:{file_id}"
            return TDOSError.SUCCESS, content_ref
            
        except IOError as e:
            print(f"Error writing to block '{block_path}': {e}")
            return TDOSError.IO_ERROR, ""
    
    def _read_file_from_block(self, content_ref: str) -> Tuple[TDOSError, str]:
        """从存储块读取文件内容"""
        if not self.handle:
            return TDOSError.INVALID_PATH, ""
        
        try:
            block_id, file_id = content_ref.split(':')
            
            if block_id not in self.handle.storage_blocks:
                return TDOSError.FILE_NOT_FOUND, ""
            
            block = self.handle.storage_blocks[block_id]
            
            if file_id not in block.file_entries:
                return TDOSError.FILE_NOT_FOUND, ""
            
            offset, size = block.file_entries[file_id]
            block_path = os.path.join(self.handle.disk_root_dir, "file", f"{block_id}.tdos")
            
            with open(block_path, 'rb') as f:
                f.seek(offset)
                content = f.read(size).decode('utf-8')
            
            return TDOSError.SUCCESS, content
            
        except (ValueError, IOError) as e:
            print(f"Error reading from block: {e}")
            return TDOSError.IO_ERROR, ""
    
    def _remove_file_from_block(self, block_id: str, file_id: str) -> TDOSError:
        """从存储块中删除文件"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        if block_id not in self.handle.storage_blocks:
            return TDOSError.FILE_NOT_FOUND
        
        block = self.handle.storage_blocks[block_id]
        
        if file_id not in block.file_entries:
            return TDOSError.FILE_NOT_FOUND
        
        # 从块信息中移除文件
        offset, size = block.file_entries[file_id]
        del block.file_entries[file_id]
        block.file_count -= 1
        block.total_size -= size
        
        return TDOSError.SUCCESS
    
    def _load_storage_blocks(self) -> TDOSError:
        """加载存储块信息"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        file_dir = os.path.join(self.handle.disk_root_dir, "file")
        if not os.path.exists(file_dir):
            return TDOSError.SUCCESS
        
        # 查找所有块文件
        for file_name in os.listdir(file_dir):
            if file_name.endswith('.tdos') and file_name.startswith('s_'):
                block_id = file_name[:-5]  # 移除.tdos扩展名
                
                # 初始化块信息
                self.handle.storage_blocks[block_id] = StorageBlock(block_id=block_id)
                
                # 读取块头信息（如果有）
                block_path = os.path.join(file_dir, file_name)
                header_path = os.path.join(file_dir, f"{block_id}.hdr")
                
                if os.path.exists(header_path):
                    try:
                        with open(header_path, 'r') as f:
                            for line in f:
                                if line.startswith('file_count:'):
                                    self.handle.storage_blocks[block_id].file_count = int(line[11:].strip())
                                elif line.startswith('total_size:'):
                                    self.handle.storage_blocks[block_id].total_size = int(line[11:].strip())
                                elif line.startswith('file:'):
                                    parts = line[5:].strip().split(':')
                                    if len(parts) >= 3:
                                        file_id = parts[0]
                                        offset = int(parts[1])
                                        size = int(parts[2])
                                        self.handle.storage_blocks[block_id].file_entries[file_id] = (offset, size)
                    except IOError:
                        # 如果无法读取头文件，忽略错误
                        pass
        
        return TDOSError.SUCCESS
    
    def _save_storage_blocks(self) -> TDOSError:
        """保存存储块信息"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        file_dir = os.path.join(self.handle.disk_root_dir, "file")
        
        for block_id, block in self.handle.storage_blocks.items():
            # 写入块头信息
            header_path = os.path.join(file_dir, f"{block_id}.hdr")
            try:
                with open(header_path, 'w') as f:
                    f.write(f"file_count:{block.file_count}\n")
                    f.write(f"total_size:{block.total_size}\n")
                    for file_id, (offset, size) in block.file_entries.items():
                        f.write(f"file:{file_id}:{offset}:{size}\n")
            except IOError as e:
                print(f"Error writing block header '{header_path}': {e}")
                return TDOSError.IO_ERROR
        
        return TDOSError.SUCCESS
    
    def _create_default_files(self, disk_root: str) -> TDOSError:
        """创建默认系统文件"""
        # 创建BIOS文件
        bios_path = os.path.join(disk_root, "S.BIOS.tdos")
        err, bios_content = self._generate_bios()
        if err != TDOSError.SUCCESS:
            return err
        
        err = self._write_file(bios_path, bios_content)
        if err != TDOSError.SUCCESS:
            return err
        
        # 创建文件树文件
        tree_path = os.path.join(disk_root, "S.fo.tdos")
        if self.handle and self.handle.root_node:
            err, tree_content = self._generate_filetree(self.handle.root_node, "")
            if err != TDOSError.SUCCESS:
                return err
            
            err = self._write_file(tree_path, tree_content)
            if err != TDOSError.SUCCESS:
                return err
        
        # 创建INIT.cnx文件
        init_path = os.path.join(disk_root, "INIT.cnx")
        init_content = "# TDOS Disk Data Parsing Algorithm\n" \
                      "# Folder algorithm: auto-add '.' and '..'\n" \
                      "# Link algorithm: for disk partitions\n" \
                      "# File algorithm: standard content storage\n"
        
        err = self._write_file(init_path, init_content)
        if err != TDOSError.SUCCESS:
            return err
        
        return TDOSError.SUCCESS
    
    def io(self, path: str, mode: str, content: Optional[str] = None) -> Tuple[TDOSError, Optional[str]]:
        """IO函数：负责磁盘文件内容的读写删操作"""
        if not path:
            return TDOSError.INVALID_PATH, None
        
        if mode == 'r':  # 读取
            return self._read_file(path)
        elif mode == 'w':  # 写入
            if content is None:
                return TDOSError.INVALID_MODE, None
            err = self._write_file(path, content)
            return err, None
        elif mode == 'm':  # 删除
            err = self._remove_file(path)
            return err, None
        else:
            return TDOSError.INVALID_MODE, None
    
    def strp(self, input_str: Optional[str], operation: int) -> Tuple[TDOSError, Optional[str]]:
        """字符串处理函数：负责磁盘文件内容撰写和解析"""
        # 0: 解析BIOS, 1: 生成BIOS, 2: 解析文件树, 3: 生成文件树
        if operation == 0:  # 解析BIOS
            if input_str is None:
                return TDOSError.INVALID_PATH, None
            err = self._parse_bios(input_str)
            return err, None
        elif operation == 1:  # 生成BIOS
            err, output = self._generate_bios()
            return err, output
        elif operation == 2:  # 解析文件树
            if input_str is None:
                return TDOSError.INVALID_PATH, None
            err = self._parse_filetree(input_str)
            return err, None
        elif operation == 3:  # 生成文件树
            if not self.handle or not self.handle.root_node:
                return TDOSError.INVALID_PATH, None
            err, output = self._generate_filetree(self.handle.root_node, "")
            return err, output
        else:
            return TDOSError.INVALID_MODE, None
    
    def loaddisk(self, disk_root: str, disk_name: str) -> TDOSError:
        """加载磁盘函数：检查并加载或创建TDOS磁盘"""
        # 检查磁盘根目录是否存在
        disk_path = Path(disk_root)
        if not disk_path.exists():
            # 目录不存在，尝试创建
            err = self.mkdir_p(disk_root)
            if err != TDOSError.SUCCESS:
                print(f"Error: Cannot create disk directory '{disk_root}': {tdos_strerror(err)}")
                return err
        elif not disk_path.is_dir():
            print(f"Error: Disk path '{disk_root}' is not a directory")
            return TDOSError.NOT_A_DIRECTORY
        
        # 创建句柄
        self.handle = TDOSHandle()
        self.handle.disk_root_dir = disk_root
        self.handle.bios_data.disk_name = disk_name
        self.handle.current_path = "/"
        self.handle.disk_modified = False
        
        # 创建必要的目录结构
        file_dir = os.path.join(disk_root, "file")
        err = self.mkdir_p(file_dir)
        if err != TDOSError.SUCCESS:
            print(f"Error: Cannot create file directory '{file_dir}': {tdos_strerror(err)}")
            self.handle = None
            return err
        
        # 检查BIOS文件是否存在
        bios_path = os.path.join(disk_root, "S.BIOS.tdos")
        if self._file_exists(bios_path):
            # 加载现有磁盘
            err, bios_content = self.io(bios_path, 'r')
            if err != TDOSError.SUCCESS:
                print(f"Error: Cannot read BIOS file '{bios_path}'")
                self.handle = None
                return TDOSError.DISK_CORRUPTED
            
            err, _ = self.strp(bios_content, 0)  # 解析BIOS
            if err != TDOSError.SUCCESS:
                print("Error: Cannot parse BIOS content")
                self.handle = None
                return TDOSError.DISK_CORRUPTED
            
            # 加载文件树
            tree_path = os.path.join(disk_root, "S.fo.tdos")
            err, tree_content = self.io(tree_path, 'r')
            if err != TDOSError.SUCCESS:
                print(f"Error: Cannot read file tree '{tree_path}'")
                self.handle = None
                return TDOSError.DISK_CORRUPTED
            
            err, _ = self.strp(tree_content, 2)  # 解析文件树
            if err != TDOSError.SUCCESS:
                print("Error: Cannot parse file tree content")
                self.handle = None
                return TDOSError.DISK_CORRUPTED
            
            # 加载存储块信息
            err = self._load_storage_blocks()
            if err != TDOSError.SUCCESS:
                print("Error: Cannot load storage blocks")
                self.handle = None
                return TDOSError.DISK_CORRUPTED
            
            print(f"Loaded existing TDOS disk: {disk_name}")
        else:
            # 创建新磁盘
            self.handle.bios_data.disk_id = f"TDOS_DISK_{int(time.time())}"
            self.handle.bios_data.algorithm_path = "INIT.cnx"
            self.handle.bios_data.root_path = "/"
            self.handle.bios_data.next_block_id = 0
            self.handle.bios_data.next_local_id = 2
            
            # 创建根节点
            self.handle.root_node = FileNode(
                name="/",
                type=FileType.DIRECTORY,
                parent_path="",
                create_time=time.time(),
                modify_time=time.time(),
                local_id="00000000"
            )
            
            # 为根节点添加特殊目录项
            self._add_special_directories(self.handle.root_node)
            
            # 创建默认系统文件
            err = self._create_default_files(disk_root)
            if err != TDOSError.SUCCESS:
                print(f"Error: Cannot create default files: {tdos_strerror(err)}")
                self.handle = None
                return err
            
            # 标记磁盘为已修改，需要保存
            self.handle.disk_modified = True
            
            print(f"Created new TDOS disk: {disk_name}")
        
        return TDOSError.SUCCESS
    
    def savedisk(self) -> TDOSError:
        """保存磁盘函数"""
        if not self.handle:
            return TDOSError.INVALID_PATH
        
        # 如果磁盘没有被修改，则不需要保存
        if not self.handle.disk_modified:
            return TDOSError.SUCCESS
        
        # 保存BIOS
        bios_path = os.path.join(self.handle.disk_root_dir, "S.BIOS.tdos")
        err, bios_content = self.strp(None, 1)  # 生成BIOS
        if err != TDOSError.SUCCESS:
            return err
        
        err, _ = self.io(bios_path, 'w', bios_content)
        if err != TDOSError.SUCCESS:
            return err
        
        # 保存文件树
        tree_path = os.path.join(self.handle.disk_root_dir, "S.fo.tdos")
        err, tree_content = self.strp(None, 3)  # 生成文件树
        if err != TDOSError.SUCCESS:
            return err
        
        err, _ = self.io(tree_path, 'w', tree_content)
        if err != TDOSError.SUCCESS:
            return err
        
        # 保存存储块信息
        err = self._save_storage_blocks()
        if err != TDOSError.SUCCESS:
            return err
        
        # 标记磁盘为未修改
        self.handle.disk_modified = False
        
        print(f"Disk saved successfully: {self.handle.bios_data.disk_name}")
        return TDOSError.SUCCESS
    
    def os(self, path: str, mode: str, content: Optional[str] = None) -> Tuple[TDOSError, Optional[str]]:
        """OS函数：对文件夹和文件的读写删操作"""
        if not self.handle or not path:
            return TDOSError.INVALID_PATH, None
        
        # 规范化路径
        err, normalized_path = self._normalize_path(path)
        if err != TDOSError.SUCCESS:
            return err, None
        
        # 查找节点
        node = self._find_node(normalized_path)
        
        if mode == 'r':  # 读取
            if not node:
                return TDOSError.FILE_NOT_FOUND, None
            
            if node.type == FileType.DIRECTORY:
                # 目录读取操作
                result = ".\n..\n"
                
                # 使用排序的ID列表按顺序遍历子节点
                for local_id in node.sorted_child_ids:
                    child = node.children_by_id[local_id]
                    # 跳过特殊目录项（它们已经在前面添加了）
                    if child.name in (".", ".."):
                        continue
                    
                    type_indicator = '/' if child.type == FileType.DIRECTORY else \
                                   '@' if child.type == FileType.LINK_FILE else ' '
                    result += f"{child.name}{type_indicator}\n"
                
                return TDOSError.SUCCESS, result
            elif node.type == FileType.REGULAR_FILE:
                # 文件读取操作
                return self._read_file_from_block(node.content_ref)
            elif node.type == FileType.LINK_FILE:
                # 链接文件读取操作
                return TDOSError.SUCCESS, node.link_target
            else:
                return TDOSError.INVALID_MODE, None
            
        elif mode == 'w':  # 写入
            # 获取父路径和基本名称
            err, parent_path = self._get_parent_path(normalized_path)
            if err != TDOSError.SUCCESS:
                return err, None
            
            err, basename = self._get_basename(normalized_path)
            if err != TDOSError.SUCCESS:
                return err, None
            
            # 检查父目录是否存在
            parent_node = self._find_node(parent_path)
            if not parent_node or parent_node.type != FileType.DIRECTORY:
                return TDOSError.NOT_A_DIRECTORY, None
            
            if node:
                # 更新现有节点
                if node.type == FileType.DIRECTORY:
                    return TDOSError.NOT_A_FILE, None
                
                if node.type == FileType.REGULAR_FILE:
                    # 更新文件内容
                    if content:
                        # 先删除旧内容
                        if ':' in node.content_ref:  # 新格式：block_id:file_id
                            try:
                                block_id, file_id = node.content_ref.split(':')
                                self._remove_file_from_block(block_id, file_id)
                            except ValueError:
                                # 如果格式不正确，忽略错误
                                pass
                        else:  # 旧格式：直接删除文件
                            content_path = os.path.join(self.handle.disk_root_dir, "file", node.content_ref)
                            try:
                                Path(content_path).unlink()
                            except OSError:
                                pass  # 忽略删除错误
                        
                        # 写入新内容
                        err, content_ref = self._write_file_to_block(content)
                        if err != TDOSError.SUCCESS:
                            return err, None
                        node.content_ref = content_ref
                        node.modify_time = time.time()
                        self.handle.disk_modified = True
                    return TDOSError.SUCCESS, None
                elif node.type == FileType.LINK_FILE:
                    # 更新链接目标
                    if content:
                        node.link_target = content
                        node.modify_time = time.time()
                        self.handle.disk_modified = True
                    return TDOSError.SUCCESS, None
                else:
                    return TDOSError.INVALID_MODE, None
            else:
                # 创建新节点
                new_type = FileType.REGULAR_FILE
                content_ref = ""
                link_target = ""
                
                if content is None:
                    # 创建目录
                    new_type = FileType.DIRECTORY
                elif content and content.startswith("link:"):
                    new_type = FileType.LINK_FILE
                    link_target = content[5:]
                elif content:
                    # 写入文件内容到存储块
                    err, content_ref = self._write_file_to_block(content)
                    if err != TDOSError.SUCCESS:
                        return err, None
                
                # 创建节点
                err, new_node = self._create_node(normalized_path, new_type, content_ref, link_target)
                if err != TDOSError.SUCCESS:
                    return err, None
                
                # 添加到父节点
                new_node.next_sibling = parent_node.first_child
                parent_node.first_child = new_node
                
                # 添加到父节点的快速查找结构
                parent_node.children_by_id[new_node.local_id] = new_node
                bisect.insort(parent_node.sorted_child_ids, new_node.local_id)
                
                parent_node.modify_time = time.time()
                
                # 如果是目录，添加特殊目录项
                if new_node.type == FileType.DIRECTORY:
                    self._add_special_directories(new_node)
                
                # 标记磁盘为已修改
                self.handle.disk_modified = True
                
                return TDOSError.SUCCESS, None
            
        elif mode == 'm':  # 删除
            if not node:
                return TDOSError.FILE_NOT_FOUND, None
            
            err, parent_path = self._get_parent_path(normalized_path)
            if err != TDOSError.SUCCESS:
                return err, None
            
            # 检查父目录是否存在
            parent_node = self._find_node(parent_path)
            if not parent_node or parent_node.type != FileType.DIRECTORY:
                return TDOSError.NOT_A_DIRECTORY, None
            
            # 递归删除节点
            err = self._remove_node(node)
            if err != TDOSError.SUCCESS:
                return err, None
            
            parent_node.modify_time = time.time()
            
            # 标记磁盘为已修改
            self.handle.disk_modified = True
            
            return TDOSError.SUCCESS, None
        
        else:
            return TDOSError.INVALID_MODE, None
"""
# 创建TDOS实例
tdos = TDOS()

# 加载或创建磁盘
err = tdos.loaddisk("~/", "MyDisk")
if err != TDOSError.SUCCESS:
    print(f"Error loading disk: {tdos_strerror(err)}")
    exit(1)

# 创建文件
err, _ = tdos.os("/test.txt", 'w', "Hello, TDOS!")
if err != TDOSError.SUCCESS:
    print(f"Error creating file: {tdos_strerror(err)}")

# 读取文件
err, content = tdos.os("/test.txt", 'r')
if err == TDOSError.SUCCESS:
    print(f"File content: {content}")

# 创建目录
err, _ = tdos.os("/mydir", 'w', None)
if err != TDOSError.SUCCESS:
    print(f"Error creating directory: {tdos_strerror(err)}")

# 列出目录内容
err, listing = tdos.os("/", 'r')
if err == TDOSError.SUCCESS:
    print(f"Directory listing: {listing}")

# 保存磁盘
err = tdos.savedisk()
if err != TDOSError.SUCCESS:
    print(f"Error saving disk: {tdos_strerror(err)}")
"""
